package com.shrw.duke.serialport;

import android.os.Handler;
import android.os.HandlerThread;

import com.odm.OdmUtil;
import com.shrw.duke.serialport.common.runnable.PortReadRunnable;
import com.shrw.duke.serialport.common.runnable.PortWriteRunnable;
import com.shrw.duke.serialport.listener.PortDataListener;
import com.shrw.duke.serialport.port.p.Port;

import java.io.FileDescriptor;
import java.io.IOException;

/**
 * Created by rw-duke on 2018/4/2.
 */

public class SerialPortManager {

    private static SerialPortManager mInstance = null;
    private HandlerThread mPortHandlerThread;
    private HandlerThread mPortWriteHandlerThread;
    private Handler mPortHandler;
    private Handler mPortWriteHandler;
    private PortReadRunnable mPortReadRunnable;

    private Port mPort;
    private FileDescriptor fd;
    private PortDataListener mPortDataListener;


    private SerialPortManager() {
        initHanlder();
    }

    public static SerialPortManager getInstance() {
        if (mInstance == null) {
            synchronized (SerialPortManager.class) {
                if (mInstance == null) {
                    mInstance = new SerialPortManager();
                }
            }
        }
        return mInstance;
    }

    private void initHanlder() {
        mPortHandlerThread = new HandlerThread("serial-port");
        mPortHandlerThread.start();
        mPortWriteHandlerThread = new HandlerThread("serial-port2");
        mPortWriteHandlerThread.start();
        mPortHandler = new Handler(mPortHandlerThread.getLooper());
        mPortWriteHandler = new Handler(mPortWriteHandlerThread.getLooper());

    }

    public SerialPortManager initPort(Port port) {
        this.mPort = port;
        mPort.initPort();
        return mInstance;
    }

    public SerialPortManager setPortDataListener(PortDataListener dataListener) {
        this.mPortDataListener = dataListener;
        return mInstance;
    }

    public void onDestroy() {
        stopReadPort();
        mPort.destroy();
        mPort = null;
        mPortDataListener = null;
        mPortHandlerThread.quit();
        mPortWriteHandlerThread.quit();
        mPortHandler.removeCallbacksAndMessages(null);
        mPortWriteHandler.removeCallbacksAndMessages(null);
    }

    /**
     * 打开串口
     *
     * @return 用来获取文件流发送接收数据
     * @throws IOException       串口打开异常
     * @throws SecurityException 不支持串口
     */
    public void startReadPort() throws IOException, SecurityException {
        fd = mPort.open();
        mPortReadRunnable = new PortReadRunnable(fd, mPortDataListener);
        mPortHandler.post(mPortReadRunnable);
    }

    public void stopReadPort() {
        if (mPortReadRunnable != null) {
            mPort.close();
            mPortReadRunnable.stop();
            mPortReadRunnable = null;
            fd = null;
        }
    }

    public void sendInstructions(String instructions) {
        sendInstructions(OdmUtil.hexStringToBytes(instructions));
    }


    public void sendInstructions(byte[] instructions) {
        if (isOpen()) {
            PortWriteRunnable writeRunnable = new PortWriteRunnable(fd, instructions);
            mPortWriteHandler.post(writeRunnable);
        }
    }

    public boolean isOpen() {
        return fd != null;
    }


}
